﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace TileEditor01
{
    public partial class Form1 : Form
    {
        TileForm tileForm = null;
        Tiles tilesRef = null;
        private Boolean mouseIsDown = false;
        private Point startMouseDown = new Point();
        public Form1()
        {
            InitializeComponent();

            tilesRef = new Tiles((int)NUDWidth.Value, (int)NUDHeight.Value, (int)NUDCol.Value, (int)NUDRow.Value, 4);
            setAutoScrollMinSize();
            //tileSetToolStripMenuItem_Click(this, EventArgs.Empty);
        }
        private void setAutoScrollMinSize()
        {
            dbPanel1.AutoScrollMinSize = new Size(tilesRef.tileWidth * tilesRef.tileColCount, tilesRef.tileHeight * tilesRef.tileRowCount);
            Graphics g = dbPanel1.CreateGraphics();
            tilesRef.bitmap_Player.SetResolution(g.DpiX, g.DpiY);
            g.Dispose();
        }
        private void tileSetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tileForm == null)
            {
                tileForm = new TileForm(tilesRef);
                tileForm.FormClosed += new FormClosedEventHandler(tile_FormClosed);
                tileForm.Apply += new ApplyEventHandler(dlg_Apply);
                tileForm.Show(this);
                tileForm.setAutoScrollMinSize();
            }
        }
        void dlg_Apply(object sender, ApplyEventArgs e)
        {
            dbPanel1.Invalidate();
        }
        void tile_FormClosed(object sender, FormClosedEventArgs e)
        {
            tileForm = null;
        }

        private void dbPanel1_Paint(object sender, PaintEventArgs e)
        {
            Point offset = new Point(0, 0);
            offset.X += dbPanel1.AutoScrollPosition.X;
            offset.Y += dbPanel1.AutoScrollPosition.Y;
            for (int x = 0; x < tilesRef.tileColCount; ++x)
            {
                for (int y = 0; y < tilesRef.tileRowCount; ++y)
                {
                    Rectangle des = new Rectangle(x * tilesRef.tileWidth + offset.X, y * tilesRef.tileHeight + offset.Y, tilesRef.tileWidth, tilesRef.tileHeight);
                    Tiles.Tile t = (Tiles.Tile)tilesRef.tileArray[x, y];
                    switch (t.tileType)
                    {
                        case Tiles.TILE_GROUND:
                            e.Graphics.DrawImage(tilesRef.bitmap_Ground, des);
                            break;
                        case Tiles.TILE_PLAYER:
                            e.Graphics.DrawImage(tilesRef.bitmap_Player, des);
                            break;
                        case Tiles.TILE_PORTAL:
                            e.Graphics.DrawImage(tilesRef.bitmap_Portal, des);
                            break;
                        case Tiles.TILE_ENEMY:
                            e.Graphics.DrawImage(tilesRef.bitmap_Enemy, des);
                            break;
                        case Tiles.TILE_SOUL:
                            e.Graphics.DrawImage(tilesRef.bitmap_Soul, des);
                            break;
                        case Tiles.TILE_SPIKES:
                            e.Graphics.DrawImage(tilesRef.bitmap_Spike, des);
                            break;
                        case Tiles.TILE_EMPTY:
                        default:
                            break;
                    }




                }
            }
            Pen pen = new Pen(Color.FromArgb(100,255,0,0));
            for (int i = 0; i <= tilesRef.tileColCount; ++i)
                e.Graphics.DrawLine(pen, i * tilesRef.tileWidth + offset.X, 0+ offset.Y, i * tilesRef.tileWidth+ offset.X, tilesRef.tileHeight * tilesRef.tileRowCount+ offset.Y);
            for (int i = 0; i <= tilesRef.tileRowCount; ++i)
                e.Graphics.DrawLine(pen, 0 + offset.X, i * tilesRef.tileHeight + offset.Y, tilesRef.tileWidth * tilesRef.tileColCount + offset.X, i * tilesRef.tileHeight + offset.Y);
            
            pen = new Pen(Color.FromArgb(255, 255, 0, 0),2);
            e.Graphics.DrawRectangle(pen, tilesRef.tileSelected.X * (int)NUDWidth.Value+1 + offset.X, tilesRef.tileSelected.Y * (int)NUDHeight.Value+1 + offset.Y, (int)NUDWidth.Value-2, (int)NUDHeight.Value-2);

        }

        private void dbPanel1_MouseMove(object sender, MouseEventArgs e)
        {
            toolStripStatusLabel1.Text = e.Location.ToString();
            if (mouseIsDown && e.Button == MouseButtons.Left)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Point p = tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
            if (mouseIsDown && e.Button == MouseButtons.Right)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Point p = tilesRef.clearTile(e.X - offset.X, e.Y - offset.Y);
                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
            if (mouseIsDown && e.Button == MouseButtons.Middle)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);

                Point p = tilesRef.selectedTile(e.X - offset.X, e.Y - offset.Y);

                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
            updateSelectedTile();
        }

        private void updateSelectedTile()
        {
            if (tilesRef.tileSelected.X >= tilesRef.tileColCount)
                return;
            if (tilesRef.tileSelected.Y >= tilesRef.tileRowCount)
                return;
            Tiles.Tile t = tilesRef.tileArray[tilesRef.tileSelected.X, tilesRef.tileSelected.Y];
            tb_type.Text = t.tileTypeToString();
            tb_portal.Text = t.portalTo;
            b_GoTo.Enabled = (t.tileType == Tiles.TILE_PORTAL)?true:false;
        }

        private void NUDHeight_ValueChanged(object sender, EventArgs e)
        {
            tilesRef.updateHeight((int)NUDHeight.Value);
            setAutoScrollMinSize();
            dbPanel1.Invalidate();
        }

        private void NUDWidth_ValueChanged(object sender, EventArgs e)
        {
            tilesRef.updateWidth((int)NUDWidth.Value);
            setAutoScrollMinSize();
            dbPanel1.Invalidate();
        }

        private void NUDCol_ValueChanged(object sender, EventArgs e)
        {
            tilesRef.updateCol((int)NUDCol.Value);
            setAutoScrollMinSize();
            dbPanel1.Invalidate();
        }

        private void NUDRow_ValueChanged(object sender, EventArgs e)
        {
            tilesRef.updateRow((int)NUDRow.Value);
            setAutoScrollMinSize();
            dbPanel1.Invalidate();
        }

        private void dbPanel1_MouseDown(object sender, MouseEventArgs e)
        {
            mouseIsDown = true;

            toolStripStatusLabel1.Text = e.Location.ToString();
            if (mouseIsDown && e.Button == MouseButtons.Left)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Point p = tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
            if (mouseIsDown && e.Button == MouseButtons.Right)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                Point p = tilesRef.clearTile(e.X - offset.X, e.Y - offset.Y);
                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
            if (mouseIsDown && e.Button == MouseButtons.Middle)
            {
                Point offset = new Point(0, 0);
                offset.X += dbPanel1.AutoScrollPosition.X;
                offset.Y += dbPanel1.AutoScrollPosition.Y;
                //tilesRef.overrideTile(e.X - offset.X, e.Y - offset.Y);
                
                Point p = tilesRef.selectedTile(e.X - offset.X, e.Y - offset.Y);

                Rectangle r = new Rectangle(tilesRef.pervTileSelected.X * (int)NUDWidth.Value + offset.X, tilesRef.pervTileSelected.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
                r = new Rectangle(p.X * (int)NUDWidth.Value + offset.X, p.Y * (int)NUDHeight.Value + offset.Y, (int)NUDWidth.Value, (int)NUDHeight.Value);
                dbPanel1.Invalidate(r);
            }
        }

        private void dbPanel1_MouseUp(object sender, MouseEventArgs e)
        {
            mouseIsDown = false;
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream myStream;
            SaveFileDialog MySaveFileDialog = new SaveFileDialog();
            MySaveFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            MySaveFileDialog.DefaultExt = "txt";
            MySaveFileDialog.FilterIndex = 2;
            MySaveFileDialog.RestoreDirectory = true;
            MySaveFileDialog.FileName = tb_file_name.Text;

            if (MySaveFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = MySaveFileDialog.OpenFile()) != null)
                {
                    int portal_count = 0;
                    List<string> portal_list = new List<string>();
                    List<string> area_list = new List<string>();

                    for (int r = 0; r < tilesRef.tileRowCount; ++r)
                    {
                        String area_string = "";
                        for (int c = 0; c < tilesRef.tileColCount; ++c)
                        {
                            Tiles.Tile t = tilesRef.tileArray[c, r];
                            switch (t.tileType)
                            {
                                case Tiles.TILE_EMPTY:
                                    area_string += ".";
                                    break;
                                case Tiles.TILE_ENEMY:
                                    area_string += "E";
                                    break;
                                case Tiles.TILE_GROUND:
                                    area_string += "X";
                                    break;
                                case Tiles.TILE_PORTAL:
                                    area_string += portal_count.ToString();
                                    String s = "";
                                    s += portal_count;
                                    s += "...";
                                    s += t.portalTo;

                                    portal_list.Add(s);

                                    ++portal_count;
                                    break;
                                case Tiles.TILE_SOUL:
                                    area_string += "S";
                                    break;
                                case Tiles.TILE_SPIKES:
                                    area_string += "T";
                                    break;
                                case Tiles.TILE_PLAYER:
                                    area_string += "P";
                                    break;
                                default:
                                    area_string += ".";
                                    break;
                            }
                        }
                        area_list.Add(area_string);
                    }

                    StreamWriter myWritter = new StreamWriter(myStream, System.Text.Encoding.ASCII);

                    myWritter.WriteLine("- end area");
                    for (int i = 0; i < area_list.Count; ++i)
                        myWritter.WriteLine(area_list.ElementAt<string>(i));
                    myWritter.WriteLine("- start area");

                    myWritter.WriteLine("- end waypoints");
                    for (int i = 0; i < portal_list.Count; ++i)
                        myWritter.WriteLine(portal_list.ElementAt<string>(i));
                    myWritter.WriteLine("- start waypoints");

                    myWritter.WriteLine("- end size");
                    myWritter.WriteLine("w..." + tilesRef.tileColCount);
                    myWritter.WriteLine("h..." + tilesRef.tileRowCount);
                    myWritter.WriteLine("- start size");

                    myWritter.Flush();
                    myStream.Close();
                    dbPanel1.Invalidate();
                }
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream myStream;
            OpenFileDialog MyOpenFileDialog = new OpenFileDialog();
            MyOpenFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            MyOpenFileDialog.DefaultExt = "txt";
            MyOpenFileDialog.FilterIndex = 2;
            MyOpenFileDialog.RestoreDirectory = true;

            if (MyOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = MyOpenFileDialog.OpenFile()) != null)
                {
                    DirectoryInfo dinfo = new DirectoryInfo(MyOpenFileDialog.FileName);
                    tb_file_name.Text = dinfo.Name;

                    StreamReader myReader = new StreamReader(myStream, System.Text.Encoding.ASCII);
                    String s;
                    List<string> str_list = new List<string>();
                    Dictionary<int, string> portal_dictionary = new Dictionary<int,string>();

                    while ((s = myReader.ReadLine()) != null)
                        str_list.Add(s);
                    myStream.Close();

                    for (int i = str_list.Count - 1; i >= 0; --i)
                    {
                        string cur_str = str_list.ElementAt<string>(i);
                        if (cur_str.Equals("- start size"))
                        {
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end size"))
                            {
                                if (cur_str.Substring(0, 4) == "w...")
                                    NUDCol.Value = int.Parse(cur_str.Substring(4));
                                if (cur_str.Substring(0, 4) == "h...")
                                    NUDRow.Value = int.Parse(cur_str.Substring(4));
                            }

                            tilesRef.tileArray = new Tiles.Tile[tilesRef.tileColCount, tilesRef.tileRowCount];
                            tilesRef.updateCol((int)NUDCol.Value);
                            tilesRef.updateRow((int)NUDRow.Value);
                        }

                        if (cur_str.Equals("- start waypoints"))
                        {
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end waypoints"))
                            {
                                int portal_number = int.Parse(cur_str.Substring(0, 1));
                                portal_dictionary.Add(portal_number, cur_str.Substring(4));
                            }
                        }

                        if (cur_str.Equals("- start area"))
                        {
                            int r = tilesRef.tileRowCount-1;

                            int tw = tilesRef.tileWidth;
                            int th = tilesRef.tileHeight;
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end area"))
                            {
                                for (int c = 0; c < cur_str.Length; ++c)
                                {
                                    char myChar = cur_str[c];
                                    if (myChar == 'P')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Player");//fake click
                                    else if (myChar == 'X')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Ground");//fake click
                                    else if (myChar == 'S')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Soul");//fake click
                                    else if (myChar == 'T')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Spike");//fake click
                                    else if (myChar == 'E')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Enemy");//fake click
                                    else if (myChar >= '0' && myChar <= '9')
                                    {
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Portal");//fake click
                                        String portal_string = "";
                                        portal_dictionary.TryGetValue(int.Parse(""+myChar),out portal_string);
                                        tilesRef.tileArray[c, r].portalTo = portal_string;
                                    }
                                }
                                --r;
                            }
                        }
                    }

                    dbPanel1.Invalidate();

                }
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tilesRef.tileArray = new Tiles.Tile[int.Parse(NUDCol.Value.ToString()),int.Parse(NUDRow.Value.ToString())];
            tb_file_name.Text = "Default.txt";
            NUDCol.Value = 10;
            NUDRow.Value = 10;
            NUDWidth.Value = 32;
            NUDHeight.Value = 32;
            dbPanel1.Invalidate();
        }

        private void dbPanel1_MouseEnter(object sender, EventArgs e)
        {
            
            dbPanel1.Focus();
        }

        private void dbPanel1_MouseLeave(object sender, EventArgs e)
        {
            this.Focus();
        }

        private void cbType_SelectedIndexChanged(object sender, EventArgs e)
        {
            tilesRef.currentType = ((ComboBox)sender).Text;
        }

        private void tb_portal_TextChanged(object sender, EventArgs e)
        {
            if (tilesRef.tileSelected.X >= tilesRef.tileColCount)
                return;
            if (tilesRef.tileSelected.Y >= tilesRef.tileRowCount)
                return;
            tilesRef.tileArray[tilesRef.tileSelected.X, tilesRef.tileSelected.Y].portalTo = ((TextBox)sender).Text;
        }

        private void b_GoTo_Click(object sender, EventArgs e)
        {
            quick_save();
            quick_load();
        }

        private void quick_load()
        {
            Stream myStream;
            OpenFileDialog MyOpenFileDialog = new OpenFileDialog();
            MyOpenFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            MyOpenFileDialog.DefaultExt = "txt";
            MyOpenFileDialog.FilterIndex = 2;
            MyOpenFileDialog.RestoreDirectory = true;
            MyOpenFileDialog.FileName = tb_portal.Text+".txt";

            if (MyOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = MyOpenFileDialog.OpenFile()) != null)
                {
                    DirectoryInfo dinfo = new DirectoryInfo(MyOpenFileDialog.FileName);
                    tb_file_name.Text = dinfo.Name;

                    StreamReader myReader = new StreamReader(myStream, System.Text.Encoding.ASCII);
                    String s;
                    List<string> str_list = new List<string>();
                    Dictionary<int, string> portal_dictionary = new Dictionary<int, string>();

                    while ((s = myReader.ReadLine()) != null)
                        str_list.Add(s);
                    myStream.Close();

                    for (int i = str_list.Count - 1; i >= 0; --i)
                    {
                        string cur_str = str_list.ElementAt<string>(i);
                        if (cur_str.Equals("- start size"))
                        {
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end size"))
                            {
                                if (cur_str.Substring(0, 4) == "w...")
                                    NUDCol.Value = int.Parse(cur_str.Substring(4));
                                if (cur_str.Substring(0, 4) == "h...")
                                    NUDRow.Value = int.Parse(cur_str.Substring(4));
                            }

                            tilesRef.tileArray = new Tiles.Tile[tilesRef.tileColCount, tilesRef.tileRowCount];
                            tilesRef.updateCol((int)NUDCol.Value);
                            tilesRef.updateRow((int)NUDRow.Value);
                        }

                        if (cur_str.Equals("- start waypoints"))
                        {
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end waypoints"))
                            {
                                int portal_number = int.Parse(cur_str.Substring(0, 1));
                                portal_dictionary.Add(portal_number, cur_str.Substring(4));
                            }
                        }

                        if (cur_str.Equals("- start area"))
                        {
                            int r = tilesRef.tileRowCount - 1;

                            int tw = tilesRef.tileWidth;
                            int th = tilesRef.tileHeight;
                            while (!(cur_str = str_list.ElementAt<string>(--i)).Equals("- end area"))
                            {
                                for (int c = 0; c < cur_str.Length; ++c)
                                {
                                    char myChar = cur_str[c];
                                    if (myChar == 'P')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Player");//fake click
                                    else if (myChar == 'X')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Ground");//fake click
                                    else if (myChar == 'S')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Soul");//fake click
                                    else if (myChar == 'T')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Spike");//fake click
                                    else if (myChar == 'E')
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Enemy");//fake click
                                    else if (myChar >= '0' && myChar <= '9')
                                    {
                                        tilesRef.overrideTile(c * tw + 3, r * th + 3, "Portal");//fake click
                                        String portal_string = "";
                                        portal_dictionary.TryGetValue(int.Parse("" + myChar), out portal_string);
                                        tilesRef.tileArray[c, r].portalTo = portal_string;
                                    }
                                }
                                --r;
                            }
                        }
                    }
                    dbPanel1.Invalidate();
                }
            }
        }

        private void quick_save()
        {
            Stream myStream;
            SaveFileDialog MySaveFileDialog = new SaveFileDialog();
            MySaveFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            MySaveFileDialog.DefaultExt = "txt";
            MySaveFileDialog.FilterIndex = 2;
            MySaveFileDialog.RestoreDirectory = true;
            MySaveFileDialog.FileName = tb_file_name.Text;

            if (MySaveFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = MySaveFileDialog.OpenFile()) != null)
                {
                    int portal_count = 0;
                    List<string> portal_list = new List<string>();
                    List<string> area_list = new List<string>();

                    for (int r = 0; r < tilesRef.tileRowCount; ++r)
                    {
                        String area_string = "";
                        for (int c = 0; c < tilesRef.tileColCount; ++c)
                        {
                            Tiles.Tile t = tilesRef.tileArray[c, r];
                            switch (t.tileType)
                            {
                                case Tiles.TILE_EMPTY:
                                    area_string += ".";
                                    break;
                                case Tiles.TILE_ENEMY:
                                    area_string += "E";
                                    break;
                                case Tiles.TILE_GROUND:
                                    area_string += "X";
                                    break;
                                case Tiles.TILE_PORTAL:
                                    area_string += portal_count.ToString();
                                    String s = "";
                                    s += portal_count;
                                    s += "...";
                                    s += t.portalTo;

                                    portal_list.Add(s);

                                    ++portal_count;
                                    break;
                                case Tiles.TILE_SOUL:
                                    area_string += "S";
                                    break;
                                case Tiles.TILE_SPIKES:
                                    area_string += "T";
                                    break;
                                case Tiles.TILE_PLAYER:
                                    area_string += "P";
                                    break;
                                default:
                                    area_string += ".";
                                    break;
                            }
                        }
                        area_list.Add(area_string);
                    }

                    StreamWriter myWritter = new StreamWriter(myStream, System.Text.Encoding.ASCII);

                    myWritter.WriteLine("- end area");
                    for (int i = 0; i < area_list.Count; ++i)
                        myWritter.WriteLine(area_list.ElementAt<string>(i));
                    myWritter.WriteLine("- start area");

                    myWritter.WriteLine("- end waypoints");
                    for (int i = 0; i < portal_list.Count; ++i)
                        myWritter.WriteLine(portal_list.ElementAt<string>(i));
                    myWritter.WriteLine("- start waypoints");

                    myWritter.WriteLine("- end size");
                    myWritter.WriteLine("w..." + tilesRef.tileColCount);
                    myWritter.WriteLine("h..." + tilesRef.tileRowCount);
                    myWritter.WriteLine("- start size");

                    myWritter.Flush();
                    myStream.Close();
                    dbPanel1.Invalidate();
                }
            }
        }
    }
}
